package com.zcoj.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zcoj.core.model.PageData;
import com.zcoj.core.model.PageWrap;
import com.zcoj.mapper.JudgeCaseMapper;
import com.zcoj.mapper.JudgeMapper;
import com.zcoj.mapper.JudgeResultMapper;
import com.zcoj.mapper.ProblemMapper;
import com.zcoj.pojo.Dto.*;
import com.zcoj.pojo.Vo.CaseVO;
import com.zcoj.pojo.Vo.JudgeCaseVo;
import com.zcoj.service.JudgerService;
import com.zcoj.service.UserService;
import com.zcoj.util.RedisCaches;
import com.zcoj.util.WrapperUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * Service实现
 * @author 剩xia的盛夏
 * @date 2023/02/24 16:16
 */
@Service
public class JudgerServiceImpl implements JudgerService {

    @Autowired
    private JudgeMapper judgeMapper;


    @Autowired
    private JudgeResultMapper judgeResultMapper;

    @Autowired
    private UserService userService;

    @Autowired
    private ProblemMapper problemMapper;
    @Autowired
    private JudgeCaseMapper judgeCaseMapper;


    @Autowired
    private RedisCaches redisCaches;
    @Override
    public Integer create(Judge judge) {
        judgeMapper.insert(judge);
        return judge.getSubmitId();
    }

    @Override
    public void deleteById(Integer id) {
        judgeMapper.deleteById(id);
    }

    @Override
    public void deleteByIdInBatch(List<Integer> ids) {
        if (CollectionUtils.isEmpty(ids)) return;
        judgeMapper.deleteBatchIds(ids);
    }

    @Override
    public void updateById(Judge judge) {
        judgeMapper.updateById(judge);
    }

    @Override
    public void updateByIdInBatch(List<Judge> judges) {
        if (CollectionUtils.isEmpty(judges)) return;
        for (Judge judge: judges) {
            this.updateById(judge);
        }
    }

    @Override
    public Judge findById(Integer id) {
        return judgeMapper.selectById(id);
    }

    @Override
    public Judge findOne(Judge judge) {
        Wrapper<Judge> wrapper = new QueryWrapper<>(judge);
        return judgeMapper.selectOne(wrapper);
    }

    @Override
    public List<Judge> findList(Judge judge) {
        if(Objects.nonNull(judge.getTid())&&judge.getTid()==0){
            judge.setTid(null);
        }
        if(Objects.nonNull(judge.getGid())&&judge.getGid()==0){
            judge.setGid(null);
        }
        if(Objects.nonNull(judge.getCid())&&judge.getCid()==0){
            judge.setCid(null);
        }

        Wrapper<Judge> wrapper = new QueryWrapper<>(WrapperUtil.blankToNull(judge));
        return judgeMapper.selectList(wrapper);
    }
  
    @Override
    public PageData<Judge> findPage(PageWrap<Judge> pageWrap) {
        IPage<Judge> page = new Page<>(pageWrap.getPage(), pageWrap.getCapacity());
        QueryWrapper<Judge> queryWrapper = new QueryWrapper<>(WrapperUtil.blankToNull(pageWrap.getModel()));
        for(PageWrap.SortData sortData: pageWrap.getSorts()) {
            if (sortData.getDirection().equalsIgnoreCase("DESC")) {
                queryWrapper.orderByDesc(sortData.getProperty());
            } else {
                queryWrapper.orderByAsc(sortData.getProperty());
            }
        }
        return PageData.from(judgeMapper.selectPage(page, queryWrapper));
    }

    @Override
    public PageData<Judge> findPageVo(PageWrap<Judge> pageWrap) {

        IPage<Judge> page = new Page<>(pageWrap.getPage(), pageWrap.getCapacity());
        Judge judge = WrapperUtil.blankToNull(pageWrap.getModel());
        QueryWrapper<Judge> queryWrapper = new QueryWrapper<>();
        for(PageWrap.SortData sortData: pageWrap.getSorts()) {
            if (sortData.getDirection().equalsIgnoreCase("DESC")) {
                queryWrapper.orderByDesc(sortData.getProperty());
            } else {
                queryWrapper.orderByAsc(sortData.getProperty());
            }
        }
        if(Objects.nonNull(judge.getPName())){
            queryWrapper.like("p_name",judge.getPName());
        }
        if(Objects.nonNull(judge.getStatus())){
            queryWrapper.eq("status",judge.getStatus());
        }
        if(Objects.nonNull(judge.getVisit())){
            queryWrapper.eq("visit",judge.getVisit());
        }
        if(Objects.nonNull(judge.getUid())&&judge.getUid()!=0){
            queryWrapper.eq("uid",judge.getUid());
        }
        if(Objects.nonNull(judge.getPid())){
            queryWrapper.eq("pid",judge.getPid());
        }
        if(Objects.nonNull(judge.getCid())&&judge.getCid()!=0){
            queryWrapper.eq("cid",judge.getCid());
        }
        if(Objects.nonNull(judge.getGid())&&judge.getGid()!=0){
            queryWrapper.eq("gid",judge.getGid());
        }
        if(Objects.nonNull(judge.getTid())&&judge.getTid()!=0){
            queryWrapper.eq("tid",judge.getTid());
        }

        queryWrapper.select("submit_id","uid","p_name","pid","username","status","time","memory","length","language","submit_time","judger");
        return PageData.from(judgeMapper.selectPage(page, queryWrapper));
    }

    @Override
    public JudgeCaseVo getJudgeDetail(Integer sid) {
        JudgeCaseVo judgeCaseVo = new JudgeCaseVo();
        Judge judge = judgeMapper.selectById(sid);
        User userServiceById=null;
        if(Objects.nonNull(judge)&&Objects.nonNull(judge.getUid())){
            userServiceById = userService.findById(judge.getUid());
        }
        if(Objects.isNull(userServiceById)){
            return judgeCaseVo;
        }
        QueryWrapper<Problem> problemQueryWrapper=new QueryWrapper<>();
        problemQueryWrapper.select("tilte").eq("id",judge.getPid());
        Problem problem = problemMapper.selectOne(problemQueryWrapper);
        if(Objects.nonNull(problem)){
            judgeCaseVo.setPid(judge.getPid())
                    .setPname(problem.getTilte());
        }

        judgeCaseVo.setUid(judge.getUid())
                .setUsername(userServiceById.getUsername())
                .setAvatar(userServiceById.getFaceUrl())
                .setLanguage(judge.getLanguage())
                .setLength(judge.getLength())
                .setTime(judge.getTime())
                .setMemory(judge.getMemory())
                .setStatus(judge.getStatus())
                .setScore(judge.getScore())
                .setSubmitTime(judge.getSubmitTime())
                .setErrorMessage(judge.getErrorMessage())
                .setCode(judge.getCode());
        QueryWrapper<JudgeCase> judgeCaseQueryWrapper=new QueryWrapper<>();
        judgeCaseQueryWrapper.eq("sid",sid);
        List<JudgeCase> judgeCases = judgeCaseMapper.selectList(judgeCaseQueryWrapper);
        List<CaseVO> caseVOS=new ArrayList<>();
        for (JudgeCase judgeCase : judgeCases) {
            CaseVO caseVo = new CaseVO();
            caseVo.setStatus(judgeCase.getStatus())
                    .setScore(judgeCase.getScore())
                    .setTime(judgeCase.getTime())
                    .setMemory(judgeCase.getMemory());
            if(judgeCase.getStatus()==-1){
                caseVo.setColor("255,0,0");
            }else {
                caseVo.setColor("0,255,0");
            }
            caseVOS.add(caseVo);
        }
        judgeCaseVo.setCaseVOS(caseVOS);
        return judgeCaseVo;
    }

    @Override
    public List<JudgeResult> findAllJudgeResult() {
        return judgeResultMapper.selectList(new QueryWrapper<>());
    }

    @Override
    public long count(Judge judge) {
        Wrapper<Judge> wrapper = new QueryWrapper<>(judge);
        return judgeMapper.selectCount(wrapper);
    }
}
